import sys
from Queue import Queue
from PyQt4.QtCore import *
from PyQt4.QtGui import *

queue = Queue()
# The new Stream Object which replaces the default stream associated with sys.stdout
# This object just puts data in a queue!
class WriteStream(object):
    def __init__(self,queue):
        self.queue = queue

    def write(self, text):
        self.queue.put(text)

# A QObject (to be run in a QThread) which sits waiting for data to come through a Queue.Queue().
# It blocks until data is available, and one it has got something from the queue, it sends
# it to the "MainThread" by emitting a Qt Signal 
class MyReceiver(QObject):
    mysignal = pyqtSignal(str)

    def __init__(self,queue,*args,**kwargs):
        QObject.__init__(self,*args,**kwargs)
        self.queue = queue
        self.break_flag = 0

    @pyqtSlot()
    def run(self):
        while True:
            if self.break_flag:
                break
            else:
                text = self.queue.get()
                self.mysignal.emit(text)

# An example QObject (to be run in a QThread) which outputs information with print
class LongRunningThing(QObject):
    def __init__(self,*args,**kwargs):
        QObject.__init__(self,*args,**kwargs)
        self.break_flag = 0

    @pyqtSlot()
    def run(self):
        for i in range(1000):
            if self.break_flag:
                break
            else:
                print i

# An Example application QWidget containing the textedit to redirect stdout to
class MyApp(QWidget):
    def __init__(self,*args,**kwargs):
        QWidget.__init__(self,*args,**kwargs)

        self.layout = QVBoxLayout(self)
        self.textedit = QTextEdit()
        self.button = QPushButton('start long running thread')
        self.button.clicked.connect(self.start_thread)
        self.layout.addWidget(self.textedit)
        self.layout.addWidget(self.button)
        self.long_running_thing = LongRunningThing()
        self.my_receiver = MyReceiver(queue)
        self.my_receiver.mysignal.connect(self.append_text)
        self.thread1 = QThread()
        self.my_receiver.moveToThread(self.thread1)
        self.thread1.started.connect(self.my_receiver.run)
        self.thread1.start()
        self.thread = QThread()

    @pyqtSlot(str)
    def append_text(self,text):
        self.textedit.moveCursor(QTextCursor.End)
        self.textedit.insertPlainText( text )

    @pyqtSlot()
    def start_thread(self):
        self.long_running_thing.moveToThread(self.thread)
        self.thread.started.connect(self.long_running_thing.run)
        self.thread.start()

    def closeEvent(self, event):
        self.my_receiver.break_flag = 1
        self.long_running_thing.break_flag = 1
        print "exit"
        self.thread.quit()
        self.thread.wait()
        self.thread1.quit()
        self.thread1.wait()
        event.accept()        
        #event.ignore()        
        #event.accept()
        #quit_msg = "Are you sure you want to exit the program?"
        #reply = QtGui.QMessageBox.question(self, 'Message', 
        #                 quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
    
        #if reply == QtGui.QMessageBox.Yes:
        #    event.accept()
        #else:
        #    event.ignore()        

# Create Queue and redirect sys.stdout to this queue
sys.stdout = WriteStream(queue)

# Create QApplication and QWidget
qapp = QApplication(sys.argv)  
app = MyApp()
app.show()

# Create thread that will listen on the other end of the queue, and send the text to the textedit in our application

qapp.exec_()
